package com.bytech.admin.biz.interceptor;

import java.lang.reflect.Method;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.bytech.common.biz.entity.blogUser.BlogUserAgent;

import org.springframework.core.Ordered;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.bytech.admin.biz.annotation.NoAdminCheck;
import com.bytech.admin.biz.exception.BlogAdminNotLoginException;
import com.bytech.common.biz.entity.base.BlogResultStatus;
import com.bytech.common.biz.service.remote.user.RemoteBlogUserService;
import com.bytech.common.config.AppGlobalConstants;
import com.bytech.common.utils.JedisClient;
import lombok.extern.slf4j.Slf4j;

/**
 * 管理后台鉴权拦截器
 * 本拦截器旨在简单实现管理后台的登录验证功能: 若需验证->获取cookie->设置session->成功放行
 *
 * @Author Zhao
 * @Create 2021/8/9 10:47
 */
@Slf4j
@Component
public class AdminAuthInterceptor implements HandlerInterceptor, Ordered {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        NoAdminCheck noAdminCheck = method.getAnnotation(NoAdminCheck.class);
        if (noAdminCheck != null) {
            return true;
        } else {
            BlogUserAgent sessionAgent = (BlogUserAgent) request.getSession().getAttribute(AppGlobalConstants.BLOG_USER_SESSION_KEY);
            if (sessionAgent != null) {
                if (!sessionAgent.isAdminUser()) {
                    // 管理后台只允许管理员登录 也就是那一个账号！允许多人登录需要引进 角色 概念，相应的权限控制就可以使用经典的RBAC权限控制模型
                    throw new BlogAdminNotLoginException(BlogResultStatus.NO_PERMISSION);
                }
                HttpSession session = request.getSession();
                session.setMaxInactiveInterval(AppGlobalConstants.BLOG_USER_SESSION_EXPIRED); // 保持session 10分钟有效
                return true;
            } else {
                // 简单处理 standalone 部署时 session 为空即视为未登录（若是集群情况其有可能在其他节点登录，此时需要同步服务器session才能避免重复在多个节点操作登录）
                // 本项目管理后台为单节点部署故 session 为空即视为未登录
                throw new BlogAdminNotLoginException(BlogResultStatus.NO_LOGIN);
            }
        }
    }

    @Override
    public int getOrder() {
        return 10;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                           @Nullable ModelAndView modelAndView) {

    }
}
